import re
import pandas as pd
from datetime import datetime, timedelta
import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk

def load_students_from_excel(template_path):
    """
    从Excel模板中读取学生名单
    """
    try:
        df = pd.read_excel(template_path)
        # 获取第一列（从第二行开始）的学生名单
        students = df.iloc[1:, 0].dropna().tolist()
        return students
    except Exception as e:
        messagebox.showerror("错误", f"读取Excel模板失败：{str(e)}")
        return []

# 定义星期几的显示名称
WEEKDAYS = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]

class App:
    def __init__(self, root):
        self.root = root
        self.root.title("读书语音统计")
        self.root.geometry("500x350")  # 增加窗口高度
        
        # 添加模板选择按钮和标签
        tk.Button(root, text="选择Excel模板", command=self.select_template).grid(row=0, column=0, padx=10, pady=10)
        self.template_label = tk.Label(root, text="未选择模板")
        self.template_label.grid(row=0, column=1, padx=10, pady=10, sticky="w")
        
        # 创建其他控件
        tk.Label(root, text="开始日期 (YYYY-MM-DD):").grid(row=1, column=0, padx=10, pady=10, sticky="w")
        self.start_date_entry = tk.Entry(root)
        self.start_date_entry.grid(row=1, column=1, padx=10, pady=10)
        
        tk.Label(root, text="结束日期 (YYYY-MM-DD):").grid(row=2, column=0, padx=10, pady=10, sticky="w")
        self.end_date_entry = tk.Entry(root)
        self.end_date_entry.grid(row=2, column=1, padx=10, pady=10)
        
        tk.Button(root, text="选择聊天记录文件", command=self.select_file).grid(row=3, column=0, padx=10, pady=10)
        self.file_label = tk.Label(root, text="未选择文件")
        self.file_label.grid(row=3, column=1, padx=10, pady=10, sticky="w")
        
        tk.Button(root, text="生成统计表", command=self.generate_stats).grid(row=4, column=0, columnspan=2, padx=10, pady=20)
        
        self.status_label = tk.Label(root, text="")
        self.status_label.grid(row=5, column=0, columnspan=2, padx=10, pady=10)
        
        self.file_path = None
        self.template_path = None
        self.students = []
    
    def select_template(self):
        template_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx")])
        if template_path:
            self.template_path = template_path
            self.template_label.config(text=template_path.split("\\")[-1] if "\\" in template_path else template_path.split("/")[-1])
            self.students = load_students_from_excel(template_path)
            if self.students:
                print(f"已加载{len(self.students)}名学生")
            else:
                messagebox.showerror("错误", "未能从模板中读取到学生名单")
    
    def select_file(self):
        file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt")])
        if file_path:
            self.file_path = file_path
            self.file_label.config(text=file_path.split("\\")[-1] if "\\" in file_path else file_path.split("/")[-1])
    
    def generate_stats(self):
        # 验证输入
        if not self.file_path:
            messagebox.showerror("错误", "请选择聊天记录文件")
            return
        
        if not self.template_path or not self.students:
            messagebox.showerror("错误", "请先选择包含学生名单的Excel模板")
            return
        
        try:
            start_date = datetime.strptime(self.start_date_entry.get(), '%Y-%m-%d').date()
            end_date = datetime.strptime(self.end_date_entry.get(), '%Y-%m-%d').date()
            
            if start_date > end_date:
                messagebox.showerror("错误", "开始日期不能晚于结束日期")
                return
        except ValueError:
            messagebox.showerror("错误", "日期格式不正确，请使用YYYY-MM-DD格式")
            return
        
        # 解析聊天记录
        try:
            result = parse_chat_log(self.file_path, start_date, end_date, self.students)
            
            # 选择保存路径
            output_path = filedialog.asksaveasfilename(defaultextension=".xlsx", filetypes=[("Excel files", "*.xlsx")])
            if not output_path:
                return
            
            # 生成Excel表格
            generate_excel(result, start_date, end_date, output_path, self.students)
            
            messagebox.showinfo("成功", f"统计表已生成：{output_path}")
            self.status_label.config(text=f"统计表已生成：{output_path}")
        except Exception as e:
            messagebox.showerror("错误", f"处理过程中出错：{str(e)}")


def extract_name(line, students):
    """
    从聊天记录行中提取学生姓名，支持一个家长对应多个孩子的情况
    """
    if not line:
        return []
    
    matched_students = []
    
    # 检查每个学生名字是否出现在行中
    for student in students:
        if student in line:
            matched_students.append(student)
            continue
        
        # 检查特殊情况，如"某某的妈妈"、"某某妈妈"等
        patterns = [
            f"{student}的妈妈", f"{student}妈妈", 
            f"{student}的爸爸", f"{student}爸爸",
            f"{student}的奶奶", f"{student}奶奶",
            f"{student}的爷爷", f"{student}爷爷",
            f"{student}的外婆", f"{student}外婆",
            f"{student}的外公", f"{student}外公",
            f"{student}姐姐", f"{student} 姐姐"
        ]
        
        for pattern in patterns:
            if pattern in line:
                matched_students.append(student)
                break
    
    return matched_students

def parse_chat_log(file_path, start_date, end_date, students):
    """
    解析聊天记录文件，提取语音记录
    """
    result = {}
    
    with open(file_path, 'r', encoding='utf-8') as f:
        content = f.read()
    
    message_blocks = re.split(r'\n\s*\n', content)
    
    for block in message_blocks:
        if not block.strip():
            continue
            
        lines = block.strip().split('\n')
        if len(lines) < 2:
            continue
            
        first_line = lines[0].strip()
        
        date_match = re.search(r'(\d{4}-\d{2}-\d{2})', first_line)
        if not date_match:
            continue
            
        current_date_str = date_match.group(1)
        try:
            current_date = datetime.strptime(current_date_str, '%Y-%m-%d').date()
            
            if current_date < start_date or current_date > end_date:
                continue
            
            if current_date_str not in result:
                result[current_date_str] = {student: False for student in students}
            
            name_part = first_line[date_match.end():].strip()
            current_names = extract_name(name_part, students)  # 现在返回的是一个列表
            
            if len(lines) > 1 and "[语音]" in lines[1]:
                for current_name in current_names:  # 为每个匹配到的学生记录语音
                    result[current_date_str][current_name] = True
                    print(f"记录语音: {current_date_str} - {current_name}")
        except ValueError:
            pass
    
    for date, students_dict in result.items():
        voice_count = sum(1 for has_voice in students_dict.values() if has_voice)
        print(f"日期 {date}: 有 {voice_count} 名学生发送了语音")
    
    return result

def generate_excel(result, start_date, end_date, output_path, students):
    """
    生成Excel表格
    """
    # 创建日期范围
    date_range = []
    current_date = start_date
    while current_date <= end_date:
        date_range.append(current_date.strftime('%Y-%m-%d'))
        current_date += timedelta(days=1)
    
    # 创建数据框架
    data = {}
    
    # 添加学生姓名列
    data['姓名'] = students
    
    # 按星期几分组添加列
    for weekday_idx, weekday_name in enumerate(WEEKDAYS):
        # 筛选出属于当前星期几的日期
        weekday_dates = [date_str for date_str in date_range 
                         if datetime.strptime(date_str, '%Y-%m-%d').weekday() == weekday_idx]
        
        if not weekday_dates:  # 如果没有该星期的日期，跳过
            continue
            
        # 为每个星期几创建一列
        data[weekday_name] = []
        
        # 填充每个学生在该星期几的得分情况
        for student in students:
            # 检查学生在该星期几的所有日期中是否有语音记录
            has_voice = False
            for date_str in weekday_dates:
                if date_str in result and result[date_str].get(student, False):
                    has_voice = True
                    break
            
            # 如果有语音记录，得分为10，否则为空
            data[weekday_name].append(10 if has_voice else '')
    
    # 计算总分
    data['合计得分'] = [sum([data[col][i] for col in data.keys() if col != '姓名' and isinstance(data[col][i], int)]) 
                    for i in range(len(students))]
    
    # 创建DataFrame
    df = pd.DataFrame(data)
    
    # 保存到Excel文件
    df.to_excel(output_path, index=False)
    
    return output_path


if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    root.mainloop()